package com.tnsw.facebookautoliker.helper.command;

import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONObject;

import com.tnsw.coreutils.MyLog;
import com.tnsw.coreutils.database.RecordBase;
import com.tnsw.facebookautoliker.database.DBManager;
import com.tnsw.facebookautoliker.database.FriendsList;
import com.tnsw.facebookautoliker.database.FriendsPost;
import com.tnsw.facebookautoliker.database.ObjectCache;
import com.tnsw.facebookautoliker.database.SelfInfo;
import com.tnsw.facebookautoliker.helper.FacebookBGManager;
import com.tnsw.facebookautoliker.helper.GeneralManager;
import com.tnsw.facebookautoliker.services.AutoLikerService;

import android.content.Context;

public class LikeManager {
	
	public static final String S_ELSE = "..else";
	public static final String S_BECOME_FRIEND = "Become friends";
	public static final String S_GROUP_CREATED = "Group Created";
	public static final String S_EVENT_CREATED = "Event Created";
	public static final String S_STATUS_UPDATE = "Status Update";
	public static final String S_POST_OTHER_WALL = "Post Other Wall";
	public static final String S_NOTE_CREATED = "Note Created";
	public static final String S_LINK_POSTED = "Link Posted";
	public static final String S_VIDEO_POSTED = "Video Posted";
	public static final String S_PHOTO_POSTED = "Photo Posted";
	public static final String S_APP_STORY237 = "App Story";
	public static final String S_COMMENT_CREATED = "Comment created";
	public static final String S_APP_STORY272 = "App Story";
	public static final String S_CHECKIN = "Checking to a place";
	public static final String S_POST_IN_GROUP = "Post in group";
	public static final String S_COMMENTS_ON_SOMETHING = "Comments on Something";
	public static final String S_LIKED_SOMETHING = "Liked Something";
	public static final String S_PHOTO_POST_WITH_APP = "Post photo with Apps";
	public static final String S_TAGGED_PHOTO = "Tagged photo";
	public static final String S_CHANGE_PHOTO_PROFILE = "Changed Photo Profile";
	public static final String S_POST_INSTAGRAM = "Posted Instagram's photo";
	public static final String S_UPDATE_COVER_PHOTO = "Updated cover photo";
	public static final String S_LIFE_EVENT = "Life Event";
	

	private String tag = "LikeManager";
	private Context context;
	
	private GeneralManager gm;
	private DBManager dbm;
	private FacebookBGManager fbm;
	
	private SelfInfo selfInfo;
	
	public LikeManager(Context context, SelfInfo selfInfo) {
		this.context = context;
		this.selfInfo = selfInfo;
		
		this.gm = GeneralManager.getInstance();
		this.dbm = DBManager.getInstance(context);
		this.fbm = FacebookBGManager.getInstance(context);
		
	}
	
	public void setSelfInfo(SelfInfo selfInfo) {
		this.selfInfo = selfInfo;
	}
	
	public static String getType(JSONObject jo, String name) {
		boolean canLike = false;
		String s = S_ELSE;
		
		try {
			int type = jo.getInt("type");
			
			switch (type) {
				case 8:
					s = S_BECOME_FRIEND;
					break;
			
				case 11:
					s = S_GROUP_CREATED;
					break;
					
				case 12:
					s = S_EVENT_CREATED;
					break;
					
				case 46:
					s = S_STATUS_UPDATE;
					break;
					
				case 56:
					s = S_POST_OTHER_WALL;
					break;
					
				case 60:
					s = S_CHANGE_PHOTO_PROFILE;
					break;
					
				case 65:
					s = S_TAGGED_PHOTO;
					break;
					
				case 66:
					s = S_NOTE_CREATED;
					break;
					
				case 80:
					s = S_LINK_POSTED;
					break;
					
				case 128:
					s = S_VIDEO_POSTED;
					break;
					
				case 130:
					s = S_VIDEO_POSTED;
					
				case 245:
					s = S_LIKED_SOMETHING;
					break;
					
				case 247:
					s = S_PHOTO_POSTED;
					break;
					
				case 237:
					s = S_APP_STORY237;
					break;
					
				case 257:
					s = S_COMMENT_CREATED;
					break;
					
				case 272:
					s = S_APP_STORY272;
					break;
					
				case 285:
					s = S_CHECKIN;
					break;
					
				case 308:
					s = S_POST_IN_GROUP;
					break;
					
				case 347:
					s = S_STATUS_UPDATE;
					break;
					
				case 373:
					s = S_UPDATE_COVER_PHOTO;
					break;
					
				case 424:
					s = S_LIFE_EVENT;
					break;
					
				case 161:
					s = S_LIKED_SOMETHING;
					break;
			}
		
		
			if (type == 347) {
				if (jo.has("app_id")) {
					String app_id = jo.getString("app_id");
					if (app_id.equals("124024574287414")) {
						s = S_POST_INSTAGRAM;
						return(s);
					}
				}
			}
			
			if (type == -1) {
				
				if (jo.has("like_info")) {
					JSONObject jLikeInfo = jo.getJSONObject("like_info");
					canLike = jLikeInfo.getBoolean("can_like");
				}
				
				
				if ( (jo.getString("message").equals("")) && (jo.getString("description").equals("") == false) &&
						(jo.getString("description").equals("null") == false) ) {
					s = S_COMMENTS_ON_SOMETHING;
				}
				
				if (name != null) {
					if (jo.getString("description").startsWith(name + " likes")) {
						s = S_LIKED_SOMETHING;
						return(s);
					}
					
					if (jo.getString("description").startsWith(name + " was tagged in")) {
						s = S_TAGGED_PHOTO;
						return(s);
					}	
				}
				
				
				if (jo.has("attachment")) {
					JSONObject jAttachment = (JSONObject) jo.get("attachment");
					if (jAttachment.has("media")) {
						JSONArray jaMedia = (JSONArray) jAttachment.getJSONArray("media");
						if ( (jaMedia.length() > 0) && (canLike == true) ) {
							JSONObject jMedia = (JSONObject) jaMedia.get(0);
							if (jMedia.getString("src").equals("") == false) {
								s = S_PHOTO_POST_WITH_APP;
							}
							
						}
					}
				}
				
			} 
			
		} catch (Exception e) {
			MyLog.e("LikeManager.getType()", "getType() - " + e.toString(), e);
		}
		
		return(s);
	}
	
	public void doUnLike(String post_id) {
		
	}
	
	private boolean likeWithFilter(FriendsPost fp, String xid, String actor_id) {
		boolean canLike = false;  // good condition to like compare with selfinfo
		AutoLikerService aService = AutoLikerService.getInstance();

		if ( (aService != null) && (aService.getSelfInfo() != null) ){
			this.selfInfo = aService.getSelfInfo();
		} else {
			ArrayList<RecordBase> a = this.dbm.getRecords(SelfInfo.class.getName(), "select * from self_info", null, 0);
			if (a != null) {
				this.selfInfo = (SelfInfo) a.get(0);
			}
			
		}
		
		if (this.selfInfo == null) {
			MyLog.e(tag, "Cannot like because no selfInfo is found");
			return(false);
		}
		
		if (this.selfInfo.like_change_profile_photo.equals("Y")) {
			if (fp.status_text.equals(S_CHANGE_PHOTO_PROFILE)) {
				canLike = true;
			}
		} else if (this.selfInfo.like_share_photo.equals("Y")) {
			
		} 
		
		if (actor_id == null) {
			MyLog.d(tag, "Not like because actor_id is null");
			return(false);
		}
		
		if (actor_id.equals("")) {
			MyLog.d(tag, "Not like because actor_id==''");
			return(false);
		}
		
		boolean doneLiked = false;
		ArrayList<RecordBase> a = this.dbm.getRecords(FriendsList.class.getName(), "select * from friends_list where id=?", new String[] {actor_id}, 0);
		if (a != null) {
			// Following this friend
			FriendsList fl = (FriendsList) a.get(0);
			if ( (fl.following.equals("Y") == true) && (fl.is_friend.equals("Y") ) ) {
				DoLikeObject like = new DoLikeObject(this.context, xid, fp.primarykey);
				like.setTag("record", fp);
				like.setTag("xid", xid);
				doneLiked = true;
				
				this.gm.addNewQueue(like, 2);	
			} else {
				if (fl.is_friend.equals("N") && (this.selfInfo.like_from_other.equals("Y")) ) {
					DoLikeObject like = new DoLikeObject(this.context, xid, fp.primarykey);
					like.setTag("record", fp);
					like.setTag("xid", xid);					
					doneLiked = true;
					
					this.gm.addNewQueue(like, 2);
				} else {
					MyLog.d(tag, "Did not like xid=" + xid + " coz this is friend but I dont follow (follow!=Y) or (not friend and like_other='N')");	
				}
							
			}
			
			
		} else {
			if (this.selfInfo.like_from_other.equals("Y")) {
				DoLikeObject like = new DoLikeObject(this.context, xid, fp.primarykey);	
				like.setTag("record", fp);
				like.setTag("xid", xid);
				doneLiked = true;
				
				this.gm.addNewQueue(like, 2);
			} else {
				MyLog.d(tag, "Did not like xid=" + xid + " coz not found actor_id from your friends");	
			}
			
		}
				
		if (doneLiked == false) {
			aService.removeWaitLike(fp.post_id);
			//MyLog.d(tag, "Not match any condition of like, immediately continue..");
			//aService.getTimerTask().likeOnWaitList();
		} else {
			MyLog.d(tag, "Liked, sent DoLikeObject to queue");
		}
		
		return(doneLiked);
	}
	
	
	/**
	 * 
	 * @param post_id	- required
	 * @param fp		- FriendsPost record, can be null
	 * @param jo		- JSONObject of fp.raw_json, can be null
	 * @param name		- name of your friend that you are going to like (not your name), can be null
	 */
	public boolean doLike(String post_id, FriendsPost fp, String name) {
		MyLog.d(tag, "Calling doLike(post_id=" + post_id + ")");
		String actor_id = "";
		boolean doneLiked = false;
		
		try {
			if (fp == null) {
				ArrayList<RecordBase> a = this.dbm.getRecords(FriendsPost.class.getName(), "select * from friends_post where post_id=?", new String[] {post_id}, 0);
				if (a == null) {
					MyLog.e(tag, "abort doLike(post_id=" + post_id + ")");
				} else {
					fp = (FriendsPost) a.get(0);
					
				}
				
			} else {
				/*
				if (fp.raw_json == null) {
					throw new Exception("FriendsPost (fp) is specified but missing fp.raw_json(null) - doLike() exits now");
					
				}
				
				if (fp.raw_json.equals("")) {
					throw new Exception("FriendsPost (fp) is specified but missing fp.raw_json('') - doLike() exits now");
				}
				*/
			}
			
			if (fp.liked.equals("Y") || (fp.liked.equals("C")) ) {
				MyLog.d(tag, "cancel like coz liked=" + fp.liked + ":" + fp.toString());
				AutoLikerService aService = AutoLikerService.getInstance();
				if (aService == null) {
					MyLog.e(tag, "Cannot get AutoLikerService, how come?");
					return(false);
				}
				
				aService.removeWaitLike(fp.post_id);
				return(false);
			}
						
			if (name == null) {
				AutoLikerService aService = AutoLikerService.getInstance();
				FriendsList fl = aService.getHashFriendsList().get(fp.actor_id);
				if (fl != null) {
					name = fl.name;
				}
			}
			
			boolean canLike = false;
			
			post_id = fp.post_id;			
			actor_id = fp.actor_id;
			
			if (fp.can_like.equals("Y")) {
				canLike = true;
			} else {
				canLike = false;
			}
			
			int type = -1;
			type = fp.type;
						
			//MyLog.d(tag, "What is it> post_id=" + post_id + ", can_like=" + canLike + ", type=" + this.getType(jo, name) + ", fp.status_text=" + fp.status_text);
			
			if (canLike == true) {
				if (fp.status_text.equals(S_PHOTO_POSTED) == true) {
					canLike = false;
					MyLog.d(tag, "To like photo, will like Photo in attachement and skip like the timeline");
					
				} else if (fp.status_text.equals(S_POST_INSTAGRAM) == true) {
					canLike = false;
					MyLog.d(tag, "To like photo, will like Photo in attachement and skip like the timeline");
				}
				
				if ( (fp.status_text.equals(S_COMMENT_CREATED) == true) ||
					 (fp.status_text.equals(S_ELSE) == true) ) {
					canLike = false;
					MyLog.d(tag, "[pending] - Cannot like '" + fp.status_text + "' right now, will be in future");
					
					fp.liked = "N";
					fp.can_like = "P";		// Pending
					this.dbm.updateRecordByPrimarykey("friends_post", fp, true);
					AutoLikerService aService = AutoLikerService.getInstance();
					aService.removeWaitLike(fp.post_id);
					doneLiked = true;
				}
				
			}
			
			if (canLike == true) {
				doneLiked = this.likeWithFilter(fp, post_id, actor_id);
			}
			
			if (fp.status_text.equals(S_LINK_POSTED) ) {
				MyLog.d(tag, "(status_text=" + fp.status_type + "), doLike exit nows, no need to like attachment");
				return(false);
			}
			
			ArrayList<RecordBase> a = this.dbm.getRecords(ObjectCache.class.getName(), "select * from object_cache where post_id=?", new String[] { post_id }, 0);
			if (a != null) {
				int i;
				for (i = 0; i < a.size(); i++) {
					ObjectCache oc = (ObjectCache) a.get(i);
					doneLiked = this.likeWithFilter(fp, oc.fbid, actor_id);
					
				}
			}
			
			if (doneLiked == false) {
				// Havn't updated record and remove from wait list, do it now..
				fp.liked = "N";
				this.dbm.updateRecordByPrimarykey("friends_post", fp, true);
				AutoLikerService aService = AutoLikerService.getInstance();
				aService.removeWaitLike(fp.post_id);
				
				//MyLog.d(tag, "Not match any condition of like, immediately continue..");
				//aService.getTimerTask().likeOnWaitList();
			} 
						
		} catch (Exception e) {
			MyLog.e(tag, "doLike - " + e.toString(), e);
			AutoLikerService aService = AutoLikerService.getInstance();
			aService.removeWaitLike(post_id);
		}
		
		return(doneLiked);
		
	}
}
